(in-package #:org.shirakumo.fraf.trial.examples)

(define-example post-processing
  :title "Post Processing Effects"
  :description "Showcasing of various built-in post-processing shaders."
  (enter (make-instance 'basic-entity :asset (assets:asset :marble-bust)) scene)
  (enter (make-instance 'skybox :texture (assets:// :sandy-beach :environment-map)) scene)
  (enter (make-instance 'environment-light :asset (assets:asset :sandy-beach)) scene)
  (enter (make-instance 'target-camera :location (vec 0.0 0.2 0.7) :target (vec 0 0.2 0) :fov 50) scene)
  (let ((render (make-instance 'pbr-render-pass))
        (map (make-instance 'ward :name :map))
        (effect (make-instance 'copy-pass :name :effect)))
    (connect (port render 'color) (port map 'previous-pass) scene)
    (connect (port map 'color) (port effect 'previous-pass) scene)))

(defmethod setup-ui ((scene post-processing-scene) panel)
  (let* ((layout (make-instance 'alloy:grid-layout :col-sizes '(120 200 T) :row-sizes '(30)))
         (focus (make-instance 'alloy:vertical-focus-list))
         (effect (node :effect scene))
         (class (type-of effect))
         (row 0))
    (macrolet ((row (label repr input &rest args)
                 `(prog2 (alloy:enter ,label layout :row row :col 0)
                      (alloy:represent ,repr ,input ,@args :focus-parent focus :layout-parent layout)
                    (incf row))))
      (labels ((repopulate ()
                 (setf row 0)
                 (alloy:clear layout)
                 (alloy:clear focus)
                 (let ((combo (row "Effect" class 'alloy:combo-set :value-set '(copy-pass negative-pass pixellate-pass color-band-pass color-adjustment-pass fisheye-pass halftone-pass bokeh-blur-pass box-blur-pass sobel-pass sharpen-pass gaussian-blur-pass kawase-blur-pass radial-blur-pass swirl-pass fxaa-pass high-pass-filter low-pass-filter chromatic-aberration-pass))))
                   (alloy:on alloy:value (class combo)
                     (change-class effect class)
                     (repopulate)))
                 (dolist (slot (c2mop:class-slots (class-of effect)))
                   (when (typep slot 'trial::uniform-slot-definition)
                     (row (princ-to-string (c2mop:slot-definition-name slot))
                          (slot-value effect (c2mop:slot-definition-name slot)) T)))))
        (repopulate)))
    (alloy:finish-structure panel layout focus)))
